package com.ruoyi.framework.aspectj;

import com.ruoyi.common.annotation.ResultFilter;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.service.ISysConfigService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.List;

@Aspect
@Component
public class ResultFilterAspect {

    @Around("@annotation(resultFilter)")
    public Object doBefore(ProceedingJoinPoint point, ResultFilter resultFilter) throws Throwable {
        Object proceed = point.proceed();
        if (proceed instanceof TableDataInfo) {
            return filterTableDataInfo((TableDataInfo) proceed, resultFilter);
        } else if (proceed instanceof AjaxResult) {
            return filterAjaxResult((AjaxResult) proceed, resultFilter);
        } else {
            return proceed;
        }
    }

    private static AjaxResult filterAjaxResult(AjaxResult proceed, ResultFilter resultFilter) throws Throwable {
        final ISysConfigService service = SpringUtils.getBean(ISysConfigService.class);
        final String video = service.selectConfigByKey("train_video");
        if (video == null || video.equals("0")) {
            return proceed;
        }
        Object o = proceed.get(AjaxResult.DATA_TAG);
        if (o instanceof List) {
            setListField(resultFilter, (List<?>) o);
        } else {
            setObjectField(resultFilter, o);
        }
        return proceed;
    }

    private static TableDataInfo filterTableDataInfo(TableDataInfo proceed, ResultFilter resultFilter) throws Throwable {
        final ISysConfigService service = SpringUtils.getBean(ISysConfigService.class);
        final String video = service.selectConfigByKey("train_video");
        if (video == null || video.equals("0")) {
            return proceed;
        }
        setListField(resultFilter, proceed.getRows());
        return proceed;
    }

    private static void setListField(ResultFilter resultFilter, List<?> list) throws IllegalAccessException {
        for (Object o : list) {
            setObjectField(resultFilter, o);
        }
    }

    private static void setObjectField(ResultFilter resultFilter, Object o) throws IllegalAccessException {
        final Class<?> aClass = o.getClass();
        setClassField(resultFilter, o, aClass);
        setClassField(resultFilter, o, aClass.getSuperclass());
    }

    private static void setClassField(ResultFilter resultFilter, Object o, Class<?> aClass) throws IllegalAccessException {
        final Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            final Object value = field.get(o);
            if (value instanceof List) {
                List valueList = (List) value;
                for (int i = 0; i < valueList.size(); i++) {
                    Object valueItem = valueList.get(i);
                    if (valueItem instanceof String && valueItem.toString().contains(resultFilter.value())) {
                        valueList.remove(i);
                        i--;
                    }
                }

            } else if (value instanceof String && value.toString().contains(resultFilter.value())) {
                field.set(o, "");
            }
        }
    }
}
